package com.yichi;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDevice;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.face.Face;
import com.google.mlkit.vision.face.FaceDetection;
import com.google.mlkit.vision.face.FaceDetector;
import com.google.mlkit.vision.face.FaceDetectorOptions;
import com.lgh.uvccamera.UVCCameraProxy;
import com.lgh.uvccamera.bean.PicturePath;
import com.lgh.uvccamera.callback.ConnectCallback;
import com.lgh.uvccamera.callback.PhotographCallback;
import com.lgh.uvccamera.callback.PictureCallback;
import com.lgh.uvccamera.callback.PreviewCallback;
import com.permissionx.guolindev.PermissionX;
import com.permissionx.guolindev.callback.RequestCallback;
import com.yichi.biz_bean.DeviceOperInfo;
import com.yichi.detector.LiveDetector;
import com.yichi.global.AppConfig;
import com.yichi.manager.OnHttpResponseListener;
import com.yichi.service.DeviceService;
import com.yichi.service.PlatformService;
import com.yichi.util.JsonUtil;
import com.yichi.util.MapUtil;
import com.yichi.util.ProgressBar;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import okhttp3.Call;
import okhttp3.Response;

public class LoginFaceFragment extends Fragment {
    private final static String TAG = "LoginFaceFragment";
    private TextView btn_smsy, btn_kssb;
    private ImageView saolianbg;
    private TextView saoliantip;

    //人脸识别
    private PreviewView previewView;
    private ImageCapture imageCapture;
    private ProcessCameraProvider cameraProvider;
    private ImageAnalysis imageAnalysis;
    // 在LoginFragment中添加
    private LiveDetector liveDetector;
    private FaceDetector facesDetector;
    private long lastTime = 0;
    private Preview preview;
    private boolean isSubmit = false;

    //usb摄像头
    private UVCCameraProxy mUVCCamera;
    private TextureView textureViewUsb;
    private ImageView imageViewUsb;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fg_face_login, container, false);
        findView(view);
        ((MainActivity) requireActivity()).setTitleTip("扫脸使用");
        setView();
        initUVCCamera();
        return view;
    }

    private void setView() {
        //扫码使用按钮
        btn_smsy.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                //人脸识别停止
//                liveDetector.stopDetection();
//                previewView.setVisibility(View.GONE);

                //usb摄像头停止
                mUVCCamera.stopPreview();

                //跳转扫码
                Fragment fragment = new LoginFragment();
                getParentFragmentManager().beginTransaction().replace(R.id.login_fragment_container, fragment).commit();

                //测试代码
//                Executors.newSingleThreadExecutor().execute(() -> {
//                    requireActivity().runOnUiThread(()->{
//                        ProgressBar progressBar = new ProgressBar(getContext());
//                        progressBar.show();
//                    });
//                    try {
//                        Thread.sleep(3000);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    requireActivity().runOnUiThread(()->{
////                        progressBar.dismiss();
//                    });
//                });
            }
        });

        //开始识别
        btn_kssb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isSubmit) {
                    return;
                }
                isSubmit = true;
                saoliantip.setText("识别中，请稍后...");
                mUVCCamera.takePicture();
            }
        });
    }

    private void findView(View view) {
        btn_smsy = view.findViewById(R.id.btn_smsy);
        btn_kssb = view.findViewById(R.id.btn_kssb);
        saolianbg = view.findViewById(R.id.saolian_bg);
        saoliantip = view.findViewById(R.id.sao_lian_tip);
        previewView = view.findViewById(R.id.previewView);
        textureViewUsb = view.findViewById(R.id.textureViewUsb);
        imageViewUsb = view.findViewById(R.id.imageViewUsb);
    }

    //=========================人脸识别开始====================================================

    private void startSaoLian() {
        PermissionX.init(this)
                .permissions(android.Manifest.permission.CAMERA)
                .request(new RequestCallback() {
                    @Override
                    public void onResult(boolean allGranted, @NonNull List<String> grantedList, @NonNull List<String> deniedList) {
                        if (allGranted) {
                            startCamera();
                        } else {
                            // deniedList 包含所拒绝的权限
                        }
                    }
                });
    }

    private void startCamera() {
        if (imageAnalysis != null) {
            imageAnalysis.clearAnalyzer();
        }
        if (liveDetector != null) {
            liveDetector.release();
        }
        if (cameraProvider != null) {
            cameraProvider.unbindAll();
        }
        if (preview != null) {
            preview.setSurfaceProvider(null);
        }
        if (liveDetector != null) {
            liveDetector.release();
            liveDetector.setCallback(null);
        }
        if (facesDetector != null) {
            facesDetector.close();
        }

        facesDetector = FaceDetection.getClient(new FaceDetectorOptions.Builder()
                .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
                .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
                .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
                .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
                .setMinFaceSize(0.2f)
                .enableTracking()
                .build());

        // 初始化检测器
        liveDetector = new LiveDetector(getContext(), new LiveDetector.LivenessCallback() {
            @Override
            public void onLiveSuccess(Bitmap verifiedFace) {
//                Toast.makeText(getActivity(),"识别成功",Toast.LENGTH_SHORT).show();
                lastTime = System.currentTimeMillis();
                if (isSubmit) {
                    return;
                }

                isSubmit = true;
                String base64 = bitmapToBase64(verifiedFace, 100);
                Log.d(TAG, "onLiveSuccess: " + base64);

                if (isAdded()) {
                    requireActivity().runOnUiThread(() -> {
                        saoliantip.setText("正在提交人脸信息，请稍后...");
                    });
                }
                submitFace(base64);

//                login.setText(R.string.saolian);
//                saolianbg.setVisibility(View.GONE);
//                saoliantip.setVisibility(View.GONE);
//                previewView.setVisibility(View.GONE);
//                saomabg1.setVisibility(View.VISIBLE);
//                saomabg2.setVisibility(View.VISIBLE);
//
//                liveDetector.stopDetection();
            }

            @Override
            public void onStatusUpdate(int code, String message) {
                Log.e(TAG, "onStatusUpdate: " + message);
//                saoliantip.setText(message);
            }

            @Override
            public void onError(String error) {
                Log.d(TAG, "onError: " + error);
            }

        });
        liveDetector.release();

        ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
                ProcessCameraProvider.getInstance(getActivity());
        cameraProviderFuture.addListener(() -> {
            try {
                cameraProvider = cameraProviderFuture.get();
                bindPreview();
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }, ContextCompat.getMainExecutor(getActivity()));

    }

    private void submitFace(String base64Image) {
        ProgressBar progressBar = new ProgressBar(getContext(), R.style.CommProgressDialog);
        progressBar.show();
        try {
            PlatformService.searchUserFace(base64Image, new OnHttpResponseListener() {
                @Override
                public void success(Call call, Response response) throws IOException {
                    progressBar.dismiss();
                    //{"code":200,"msg":"操作成功","data":{"userInfo":{"createDept":null,"createBy":null,"createTime":"2025-01-02 17:22:32","updateBy":1,"updateTime":"2025-03-25 11:50:26","tenantId":"000000","id":230,"inviteUserId":228,"realName":"游客","idCard":null,"phone":"13834538606","openId":"owR6L7Xzp_L8HA_moXuTRrXwvuN4","unionId":null,"nickName":null,"headImg":null,"city":null,"country":null,"province":null,"isDevOps":0,"state":1,"faceId":"cde6d6c4998a3764c3857f6becc4a9c2"},"token":"cD8QoxH7QyR9FqWDFWKF0w=="}}
                    String s = response.body().string();
                    Map<String, Object> map;
                    try {
                        map = JsonUtil.parseMap(s);
                    } catch (Exception e) {
                        requireActivity().runOnUiThread(() -> {
                            imageViewUsb.setVisibility(View.GONE);
                            saoliantip.setText("识别错误：" + s);
                        });
                        isSubmit = false;
                        return;
                    }
                    Integer code = MapUtil.getInteger(map, "code");
                    String msg = MapUtil.getString(map, "msg");
                    if (code != 200) {
                        requireActivity().runOnUiThread(() -> {
                            imageViewUsb.setVisibility(View.GONE);
                            saoliantip.setText("识别错误：" + msg);
                        });
                        isSubmit = false;
                        return;
                    }
                    Map dataMap = MapUtil.getMap(map, "data");
                    if (dataMap == null) {
                        requireActivity().runOnUiThread(() -> {
                            imageViewUsb.setVisibility(View.GONE);
                            saoliantip.setText("识别错误：平台未返回数据");
                        });
                        isSubmit = false;
                        return;
                    }
                    //识别成功
                    saoliantip.setText("人脸校验成功");
                    String token = MapUtil.getString(dataMap, "token");
                    AppConfig.platFormToken = token;
                    Map userMap = MapUtil.getMap(dataMap, "userInfo");
                    String realName = MapUtil.getString(userMap, "realName");
                    //机器是否空闲
                    if (DeviceService.inst.getDeviceOperInfo() != null) {
                        requireActivity().runOnUiThread(() -> {
                            imageViewUsb.setVisibility(View.GONE);
                            saoliantip.setText("设备正在运行中，请稍后再试！");
                        });
                        isSubmit = false;
                        return;
                    }
                    DeviceOperInfo deviceOperInfo = new DeviceOperInfo();
                    DeviceService.inst.setDeviceOperInfo(deviceOperInfo);
                    deviceOperInfo.setUserName(realName);
                    //跳转
                    if (isAdded()) {
                        requireActivity().runOnUiThread(() -> {
                            MainActivity mainActivity = (MainActivity) requireActivity();
                            mainActivity.goFaceSelectOps(realName);
                        });
                    }
                }

                @Override
                public void failed(Call call, IOException e) {
                    progressBar.dismiss();
                    isSubmit = false;
                }
            });
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
            progressBar.dismiss();
            isSubmit = false;
        }
    }

    private void bindPreview() {
        preview = new Preview.Builder().build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        imageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build();

        CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
        cameraProvider.unbindAll();

        // 添加图像分析用例
        imageAnalysis = new ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) // 修改策略
                .build();

        imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(getActivity()), imageProxy -> {
            try {
                analyzeFace(imageProxy);
            } finally {
                imageProxy.close();
            }
        });
        cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture, imageAnalysis);

    }

    // 修改analyzeFace方法
    @OptIn(markerClass = ExperimentalGetImage.class)
    private void analyzeFace(@NonNull ImageProxy image) {
        if (System.currentTimeMillis() - lastTime < 1000) {
            Log.d(TAG, "与上次检测时间太近");
            return;
        } else if (liveDetector.isStopDetection()) {
            liveDetector.startDetection();
        }
        Bitmap bitmap = image.toBitmap();
        InputImage inputImage = InputImage.fromBitmap(
                bitmap,
                image.getImageInfo().getRotationDegrees()
        );

        facesDetector.process(inputImage)
                .addOnSuccessListener(faces -> {
                    if (faces.isEmpty()) return;
                    for (Face face : faces) {
                        liveDetector.analyze(face, bitmap);
                    }
                })
                .addOnFailureListener(e -> Log.e(TAG, "人脸检测失败", e))
                .addOnCompleteListener(result -> image.close());
    }

    private String bitmapToBase64(Bitmap bitmap, int quality) {
        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOS);
        return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
    }

    //==================================人脸识别结束==============================

    //==================================USB摄像头开始=============================

    private void initUVCCamera() {
        mUVCCamera = new UVCCameraProxy(getContext());
        // 已有默认配置，不需要可以不设置
        mUVCCamera.getConfig()
                .isDebug(true)
                .setPicturePath(PicturePath.APPCACHE)
                .setDirName("uvccamera")
                .setProductId(0)
                .setVendorId(0);
        mUVCCamera.setPreviewTexture(textureViewUsb);
//        mUVCCamera.setPreviewSurface(mSurfaceView);
//        mUVCCamera.registerReceiver();

//        mUVCCamera.setConnectCallback(null);
        mUVCCamera.setConnectCallback(new ConnectCallback() {
            @Override
            public void onAttached(UsbDevice usbDevice) {
                mUVCCamera.requestPermission(usbDevice);
            }

            @Override
            public void onGranted(UsbDevice usbDevice, boolean granted) {
                if (granted) {
                    mUVCCamera.connectDevice(usbDevice);
                }
            }

            @Override
            public void onConnected(UsbDevice usbDevice) {
                mUVCCamera.openCamera();
            }

            @Override
            public void onCameraOpened() {
                mUVCCamera.setPreviewSize(640, 480);
//                mUVCCamera.setPreviewSize(640, 640);
                mUVCCamera.startPreview();
            }

            @Override
            public void onDetached(UsbDevice usbDevice) {
                mUVCCamera.closeCamera();
            }
        });

        mUVCCamera.setPhotographCallback(new PhotographCallback() {
            @Override
            public void onPhotographClick() {
                mUVCCamera.takePicture();
//                mUVCCamera.takePicture("test.jpg");
            }
        });

        mUVCCamera.setPreviewCallback(new PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] yuv) {

            }
        });

        mUVCCamera.setPictureTakenCallback(new PictureCallback() {
            @Override
            public void onPictureTaken(String path) {
                imageViewUsb.setVisibility(View.VISIBLE);
                imageViewUsb.setImageURI(null);
                imageViewUsb.setImageURI(Uri.parse(path));

                //压缩提交
                String base64Image = convertImageToBase64AndCompress(path);
                submitFace(base64Image);
            }
        });
    }

    // 将图片转换为Base64并压缩
    private String convertImageToBase64AndCompress(String path) {
        try {
            // 读取图片文件
            File imageFile = new File(path);
            FileInputStream fileInputStream = new FileInputStream(imageFile);
            Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);

            // 压缩图片（设置压缩质量为80）
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream);

            byte[] byteArray = byteArrayOutputStream.toByteArray();

            // 转换为Base64
            return Base64.encodeToString(byteArray, Base64.NO_WRAP);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //==================================USB摄像头结束=============================

}
